package com.lfs.dispatcher.config;

import com.lfs.dispatcher.message.MessageDelegateChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

;

@Configuration
public class RabbitMQConfig {

    @Value("${order_charge_rabbitmq_queue}")
    private String orderChargeQueue;

    @Value("${order_charge_rabbitmq_exchange}")
    private String orderChargeExchange;

    @Value("${order_charge_rabbitmq_routing_key}")
    private String orderChargeRoutingKey;

    @Value("${spring.rabbitmq.host}")
    private String host;

    @Value("${spring.rabbitmq.port}")
    private String port;

    @Value("${spring.rabbitmq.username}")
    private String username;

    @Value("${spring.rabbitmq.password}")
    private String password;

    @Value("${spring.rabbitmq.listener.concurrency}")
    private Integer coucurrency;

    @Value("${spring.rabbitmq.listener.max-concurrency}")
    private Integer maxConcurrency;

    @Value("${spring.rabbitmq.listener.prefetch}")
    private Integer prefetch;

    @Autowired
    private CachingConnectionFactory connectionFactory;

    @Autowired
    private SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer;

    private Logger logger = LoggerFactory.getLogger(RabbitMQConfig.class);

    /**
     * 单一消费者
     * @return
     */
    @Bean(name = "singleListenerContainer")
    public SimpleRabbitListenerContainerFactory listenerContainer(){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setConcurrentConsumers(1);
        factory.setMaxConcurrentConsumers(1);
        factory.setPrefetchCount(1);
        factory.setTxSize(1);
        factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
        return factory;
    }

    /**
     * 多个消费者
     * @return
     */
    @Bean(name = "multiListenerContainer")
    public SimpleRabbitListenerContainerFactory multiListenerContainer(){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factoryConfigurer.configure(factory,connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setAcknowledgeMode(AcknowledgeMode.NONE);
        factory.setConcurrentConsumers(coucurrency);
        factory.setMaxConcurrentConsumers(maxConcurrency);
        factory.setPrefetchCount(prefetch);
        return factory;
    }

    @Bean(name = "userOrderQueue")
    public Queue orderChargeQueue(){
        return new Queue(orderChargeQueue,true);
    }


    @Bean
    public FanoutExchange orderChargeExchange(){
        return new FanoutExchange(orderChargeExchange,true,false);
    }

    @Bean
    public Binding userOrderBinding(){
        return BindingBuilder.bind(orderChargeQueue()).to(orderChargeExchange());
    }

    @Autowired
    private MessageDelegateChannel messageDelegateChannel;

    @Bean
    public SimpleMessageListenerContainer listenerContainerUserOrder(@Qualifier("userOrderQueue") Queue userOrderQueue){
        SimpleMessageListenerContainer container=new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);

        //TODO：并发配置
        container.setConcurrentConsumers(coucurrency);
        container.setMaxConcurrentConsumers(maxConcurrency);
        container.setPrefetchCount(prefetch);

        //TODO:消息确认机制
        container.setQueues(userOrderQueue);
        container.setMessageListener(messageDelegateChannel);
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);

        return container;
    }
}